#pragma once
#include <vector>
#include <queue>
#include <mutex>
#include <thread>
#include <functional>
#include <atomic>
#include <cstdint>
#include <map>
#include <condition_variable>
#include <fcntl.h>       
#include <sys/mman.h>    
#include <sys/stat.h>   
#include "ser_datapack.h"
#include "ser_system.h"
#include <iomanip> 
#include <sstream> 
#include <semaphore.h>
#include <sys/types.h>
#include <cstdlib>
#include <ctime>
#include "mgr_tracedata.h"

typedef struct
{
    uint8_t ReadVer;
    uint8_t PID_Left;
    uint8_t PID_Right;
    uint8_t PID_Stand;
    uint8_t PID_Ster; 
}Trace_SendFlag_Typedef;

class TCPManager {
public:
    using ErrorCallback = std::function<void(const std::string&)>;
    
    enum class Priority {
        HIGH,    
        NORMAL,  
        LOW      
    };

    static TCPManager& getInstance();

    bool init(const char* ip, int port);

    void shutdown();

    void registerErrorCallback(ErrorCallback cb);

    bool sendImmediate(const uint8_t* data, size_t len);

    void sendBuffered(const uint8_t* data, size_t len, Priority priority = Priority::NORMAL);

    bool sendFile(const std::string& filePath, size_t chunkSize = 1024 * 1024); // 默认分块大小 1MB

    struct PerformanceStats {
        size_t totalSent = 0;
        size_t totalFailed = 0;
        size_t queueSize = 0;
        size_t totalReceived = 0;
    };
    PerformanceStats getPerformanceStats() const;

private:
    TCPManager();
    ~TCPManager();

    void sendThread();

    void receiveThread();

    bool rawSend(const uint8_t* data, size_t len);

    bool reconnect();

    void notifyError(const std::string& msg);

    std::vector<uint8_t> encodePacket(const uint8_t* data, size_t len);

    int sockfd_ = -1;
    std::atomic<bool> running_{false};
    std::atomic<bool> ReciveThereadSwitch_{false};
    std::string serverIp_;
    int serverPort_ = 0;

    std::map<Priority, std::queue<std::vector<uint8_t>>> bufferQueues_;
    std::mutex queueMutex_;
    std::condition_variable queueCond_;

    ErrorCallback errorCallback_;
    std::mutex callbackMutex_;

    mutable std::mutex statsMutex_;
    size_t totalSent_ = 0;
    size_t totalFailed_ = 0;
    size_t totalReceived_ = 0;

    std::thread sendThread_;
    std::thread receiveThread_;

};

int app_net_handle(void);
void App_Net_5msCycle(void);